package com.etime.shycourse.services.wxcoupon.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etime.shy.common.BaseMessage;
import com.etime.shycourse.dao.*;
import com.etime.shycourse.dto.CouponMyDto;
import com.etime.shycourse.dto.CouponRangeDto;
import com.etime.shycourse.dto.CurrentUser;
import com.etime.shycourse.dto.UseVoucherParam;
import com.etime.shycourse.orde.dao.OrderdetailMapper;
import com.etime.shycourse.orde.dao.OrdersMapper;
import com.etime.shycourse.orde.pojo.Orderdetail;
import com.etime.shycourse.orde.pojo.Orders;
import com.etime.shycourse.orde.utils.IdWorker;
import com.etime.shycourse.pojo.*;
import com.etime.shycourse.services.wxcoupon.interfaces.WXCouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 微信小程序端与优惠券相关的服务层实现类
 */
@Service
public class WXCouponServiceImpl implements WXCouponService {

    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private CouponreciveMapper couponreciveMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private PackageimportcourseMapper packageimportcourseMapper;
    @Autowired
    private CouponlogMapper couponlogMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrderdetailMapper orderdetailMapper;
    /**
     * 根据活动id查询活动所包含的可用优惠券列表
     *
     * @param activityid 活动id
     * @return
     */
    @Override
    public List<Coupon> selectCouponListByActivityId(Integer activityid) {
        return couponMapper.selectCouponListByActivityId(activityid);
    }

    /**
     * 根据userid查询用户的可用优惠券列表
     *
     * @param userid
     * @return
     */
    @Override
    public List<CouponMyDto> selctMyCouponList(Integer userid) {
        return couponMapper.selectMyCouponList(userid);
    }

    /**
     * 根据优惠券id查询优惠券的使用范围
     *
     * @param couponid 优惠券id
     * @return
     */
    @Override
    public List<CouponRangeDto> selectCouponRangeList(Integer couponid) {
        return couponMapper.selectVoucherRang(couponid);
    }

    /**
     * 根据优惠券id查询一条优惠券的详细信息
     *
     * @param couponid
     * @return
     */
    @Override
    public Coupon selectCouponById(Integer couponid) {
        return couponMapper.selectById(couponid);
    }

    /**
     * 根据优惠券领取id查询优惠券详细信息
     *
     * @param reciveid 优惠券领取id
     * @return
     */
    @Override
    public CouponMyDto selectCouponByReciveId(Integer reciveid) {
        return couponMapper.selectCouponByReciveId(reciveid);
    }

    /**
     * 使用兑换券兑换课程或者课程包的服务层
     * 业务逻辑：
     * 1、判断用户是否登录，token是否存在。不存在返回-2
     * 2、查询元数据：
     *    2.1 判断，如果兑换的是课程包，则从课程包中查询出所有的课程列表。
     *        如果是课程，则需要获取到所有的课程列表
     *    2.2 查询优惠基本信息
     *    2.3 查询优惠券领取详细信息
     * 3、保存优惠券的使用记录；
     * 4、保存优惠券使用记录日志；
     * 5、创建订单
     * 6、创建订单明细
     * @param param 参数
     * @param user  当前登录用户
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseMessage useVoucher(UseVoucherParam param, CurrentUser user) {
        BaseMessage msg = new BaseMessage();
        //查询优惠券详细信息
        Coupon coupon = selectCouponById(param.getCouponid());
        //查询优惠券领取的详细信息
        Couponrecive couponrecive = couponreciveMapper.selectById(param.getCouponreciveid());
        //判断优惠券的领取人与当前登录用户是否是同一个人，如果不是则返回非法操作
        if(!user.getUser().getUserid().equals(couponrecive.getCouponreciveuserid())){
            msg.setCode(-3);
            msg.setMsg("登录用户与优惠券的拥有者不同，属于非法操作。");
            return msg;
        }
        List<Course> courseslist = null;
        //查询课程列表
        if(param.getCourseorpackage() == 1){
            //课程
            courseslist = selectCourseListByCourseIds(param.getIdlist());
        }else{
            //课程包
            courseslist = selectCourseListByPackageids(param.getIdlist());
        }
        if(courseslist == null || courseslist.size() == 0){
            msg.setCode(-4);
            msg.setMsg("兑换券中没有可以兑换的课程");
            return msg;
        }
        try{
            // 开始执行兑换逻辑
            // 3、保存优惠券的使用记录；
            savecouponrecive(couponrecive);
            //4、保存优惠券使用记录日志；
            savecouponlog(couponrecive,user);
            //5、创建订单
            Orders orders = saveOrder(coupon,couponrecive,courseslist,user);
            if(orders == null){
                throw new Exception("创建订单失败");
            }
            //6、订单明细
            saveOrderDetail(orders,courseslist,user);
            msg.setCode(1);
            msg.setMsg("兑换课程成功，请到我的课程中查看");
        }catch (Exception e){
            e.printStackTrace();
            msg.setCode(-1);
            msg.setMsg("兑换课程失败，请重新兑换或者联系管理员");
        }
        return msg;
    }

    /**
     * 保存优惠券使用记录
     * @param couponrecive
     * @return
     */
    private int savecouponrecive(Couponrecive couponrecive){
        couponrecive.setCouponrecivestate(2);
        couponrecive.setCouponrecivestatetime(new Date());
        return couponreciveMapper.updateById(couponrecive);
    }

    /**
     * 保存优惠券使用日志记录
     * @param couponrecive
     * @param user
     * @return
     */
    private int savecouponlog(Couponrecive couponrecive,CurrentUser user){
        Couponlog couponlog = new Couponlog();
        couponlog.setCouponid(couponrecive.getCouponid());
        couponlog.setCouponlongreciveid(couponrecive.getCouponreciveid());
        couponlog.setCouponno(couponrecive.getCouponno());
        couponlog.setCouponloguserid(user.getUser().getUserid());
        couponlog.setCouponlogusername(user.getUser().getUsertruename()+
                "("+user.getUser().getNickname()+")");
        couponlog.setCouponlogtype(2);
        couponlog.setCouponlogtime(new Date());
        couponlog.setCouponlogdesc("");
        return couponlogMapper.insert(couponlog);
    }

    /**
     * 根据课程id集合查询出课程列表
     * @param ids
     * @return
     */
    private List<Course> selectCourseListByCourseIds(List<Integer> ids){
        return courseMapper.selectBatchIds(ids);
    }

    /**
     * 根据课程包id集合查询课程列表
     * @param ids
     * @return
     */
    private List<Course> selectCourseListByPackageids(List<Integer> ids){
        QueryWrapper<Packageimportcourse> wrapper = new QueryWrapper<>();
        wrapper.in("packageid",ids);
        List<Packageimportcourse> packageimportcourseList = packageimportcourseMapper.selectList(wrapper);
        //使用set去掉课程包中课程存在的共有课程
        Set<Integer> courseids = new HashSet<>();
        for(Packageimportcourse c : packageimportcourseList){
            courseids.add(c.getImportcourseid());
        }
        return courseMapper.selectBatchIds(courseids);
    }

    /**
     * 创建订单
     * @param coupon 优惠券基本信息
     * @param couponrecive 优惠券领取信息
     * @param courseList 课程列表（用于计算订单总额）
     * @param user 下单用户
     * @return
     */
    private Orders saveOrder(Coupon coupon,Couponrecive couponrecive,List<Course> courseList,CurrentUser user){

        Orders orders = new Orders();
        IdWorker idWorker = new IdWorker();
        orders.setOrderno(idWorker.nextId()+"");
        orders.setOrderuserid(user.getUser().getUserid());
        orders.setOrderusertruename(user.getUser().getUsertruename()+"("+user.getUser().getNickname()+")");
        //计算应付金额
        BigDecimal orderpayamount = new BigDecimal(0);
        for(Course c: courseList){
            orderpayamount = orderpayamount.add(c.getCourseprice());
        }
        orders.setOrderpayamount(orderpayamount);
        //支付类型3--使用兑换券兑换。
        orders.setOrderpricetype(3);
        //订单状态完成
        orders.setOrderstate(2);
        orders.setOrderpaycash(new BigDecimal(0));
        orders.setOrderpaycoin(new BigDecimal(0));
        orders.setOrderpaytime(new Date());
        orders.setOrderpayment("兑换券");
        orders.setOrderfinishtime(new Date());
        orders.setOrdercreateuserid(user.getUser().getUserid());
        orders.setOrdercreatename(user.getUser().getUsertruename()+"("+user.getUser().getNickname()+")");
        orders.setOrdercreatereason("使用兑换券进行课程兑换");
        orders.setOrdercreatetime(new Date());
        orders.setOrderupdatetime(new Date());
        orders.setOrdercouponreciveid(couponrecive.getCouponreciveid());
        orders.setCouponno(couponrecive.getCouponno());
        orders.setOrdercouponmoney(orderpayamount);
        orders.setOrderpaycoinmoney(new BigDecimal(0));
        orders.setOrdercoupondemo("使用兑换券直接兑换课程");
        int rtn = ordersMapper.insert(orders);
        if(rtn>0){
            return orders;
        }else{
            return null;
        }
    }

    /**
     * 保存订单明细
     * 业务逻辑：
     * 1、遍历课程列表
     * 2、判断用户是否已经购买了该课程；
     *    2.1 如果有，则添加该课程的到期时间（延长时间）；
     *    2.2 如果没有，则添加订单明细
     * @param orders 订单
     * @param courseList 课程列表
     * @return
     */
    private int saveOrderDetail(Orders orders,List<Course> courseList,CurrentUser user){
        for(Course course : courseList){
            //判断用户是否已经购买了该课程；
            List<Orderdetail> orderdetailList = orderdetailMapper.selectOrderDetailByUseridAndCourseId(
              user.getUser().getUserid(),
              course.getCourseid()
            );
            if(orderdetailList!=null && orderdetailList.size()>0){
                //已经购买过该图书，那么修改原来的记录，将课程到期时间延长
                for(Orderdetail od : orderdetailList) {
                    Calendar c = Calendar.getInstance();
                    c.setTime(od.getOdendtime());
                    c.add(Calendar.DAY_OF_YEAR,course.getCoursevaliddays());
                    od.setOdendtime(c.getTime());
                    orderdetailMapper.updateById(od);
                }
            }else{
                //没有购买，则添加订单详情
                Orderdetail od = new Orderdetail();
                od.setOrderid(orders.getOrderid());
                od.setOdgoodstype(1);
                od.setOdcourseid(course.getCourseid());
                od.setOdcoursename(course.getCoursetitle());
                od.setOdprice(course.getCourseprice());
                od.setOdorigninprice(course.getCourseoriginprice());
                od.setOdcoinprice(course.getCoursecoinprice());
                od.setOdcoinmaxpoint(course.getCoursecoinmaxpoint());
                od.setOdsalertakes(new BigDecimal(0));
                od.setOdtectakes(new BigDecimal(0));
                od.setOdsalersettlemented(0);
                od.setOdtecsettlement(0);
                od.setOdcoursestate(1);
                //到期时间
                Calendar c = Calendar.getInstance();
                c.setTime(new Date());
                c.add(Calendar.DAY_OF_YEAR,course.getCoursevaliddays());
                od.setOdendtime(c.getTime());
                orderdetailMapper.insert(od);
            }
        }
        return 1;
    }

}
